package io;
/**
 * XMLControler
 * 
 * 
 * Parses an XML file using SAX parser, giving the ability to manage content and save back modified file
 */

import java.io.*;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.jdom.*;
import org.jdom.input.SAXBuilder;
import org.jdom.Document;
import org.jdom.output.*;
import org.jdom.xpath.XPath;

import utils.EDCResource;

public class XMLControler {

	public static Document document;
	public static Element root;

	/**
	 * @param fichier
	 * @throws Exception
	 */
	public static void readXMLFile(String fichier) throws Exception
	{

		SAXBuilder sxb = new SAXBuilder();
		File f = new File(fichier);
		document = sxb.build(f);
		root = document.getRootElement();
	}

	public static void initXMLFile(String file) throws Exception {
		File f = new File(file);
		boolean b = f.createNewFile();
		// File did not exist and was created
		if(b) {
			document = new Document();
			root = new Element("catalog");
			document.setRootElement(root);
			DocType doctype = new DocType("catalog", "dtdcatalog.dtd");
			document.setDocType(doctype);

			// create elements
//			if(!hasDTDItem()) {
//			File folder = new File(EDCResource.dtdFolderPath);
//			File[] files = folder.listFiles(EDCResource.dtdFilter);
			File[] files = EDCResource.dtds;
			for (int i=0; i<files.length; i++) {
				addDTDNode(files[i].getName(), files[i].getPath());
			}
//			}

			saveXMLFile(file);
		}

	}


	/**
	 * @param fichier
	 * @throws Exception
	 */
	public static void saveXMLFile(String fichier) throws Exception
	{
		XMLOutputter sortie = new XMLOutputter(Format.getPrettyFormat());
		sortie.output(document, new FileOutputStream(fichier));
	}


	/**
	 * @param nom_menu
	 * @return
	 */
	public static String getDTDName(int index){
		return getAttribut("//dtditem[position()="+index+"]/@nom");
	}

	/**
	 * @param xpathExpr
	 * @return
	 */
	private static String getAttribut(String xpathExpr)
	{
		Attribute courant;
		String attr = null;
		try{
			//XPath xpa = XPath.newInstance("//dtditem/@nom");  
			courant = (Attribute)XPath.selectSingleNode(document,xpathExpr);
			attr=courant.getValue();
		}
		catch(JDOMException jdom){
			jdom.printStackTrace();
		}
		return attr;
	}

	/**
	 * Méthode retournant tous les éléments dtditem du fichier XML
	 * @return
	 */
	public static List getDTDItem(){
		List res = null;
		try{
			res = XPath.selectNodes(document, "//dtditem");
		}
		catch(JDOMException jdom){
			jdom.printStackTrace();
		}
		return res;
	}

	public static Element getDTDItem(int index) {
		Element elt = null;
		try {
			elt = (Element)(XPath.selectSingleNode(document, "//dtditem[position()="+index+"]"));
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return elt;
	}

	public static Vector<Vector<Object>> getData() {
//		if(!hasDTDItem()) {
//		File f = new File(EDCResource.dtdFolderPath);
//		File[] files = f.listFiles(EDCResource.dtdFilter);
//		for (int i=0; i<files.length; i++) {
//		addDTDNode(files[i].getName(), files[i].getPath());
//		}
//		}
		Vector<Vector<Object>> v = new Vector<Vector<Object>>();
		List l = null;
		Element e;
		try{
			l = XPath.selectNodes(document, "//dtditem");
		}
		catch(JDOMException jdom){
			jdom.printStackTrace();
		}
		Iterator iter = l.iterator();
		while(iter.hasNext()){
			e = (Element) iter.next();
			Vector<Object> row = new Vector<Object>();

			row.add(0, e.getAttributeValue("nom")); //name
			row.add(1, e.getChildText("url")); // link
			row.add(2, e.getChildText("description")); // description
			row.add(3, ""); // comment
			v.add(row);
		}
		return v;

	}

	public static boolean hasDTDItem() {
		boolean res = false;
		List l = null;
		try {
			l = XPath.selectNodes(document, "dtditem");
			if(l.size()>0)
				res = true;
		}
		catch(JDOMException jdom){
			jdom.printStackTrace();
		}
		return res;
	}

	//Add a DTD node
	public static void addDTDNode(String dtdName, String dtdPath){
		try{
			//Create a dtditem element
			Element dtdItem = new Element("dtditem");
			dtdItem.setAttribute("nom",dtdName);

			//Create an URL element
			Element urlElt = new Element("url");
			urlElt.addContent(dtdPath);
			dtdItem.addContent(urlElt);

			//Create a description element
			Element descElt = new Element("description");
			dtdItem.addContent(descElt);

			root.addContent(dtdItem);
		}
		catch(Exception e){
			System.out.println("Erreur de lecture du fichier XML");	
			e.printStackTrace();
		}
	}

	public static boolean isXMLContainsFile(String fileName){
		boolean res = false;
		try{
			List listNodes = XPath.selectNodes(document,"//file[@name='"+fileName+"']");
			if(listNodes.size()==0)	res = false;
			else res = true;
		}
		catch(JDOMException jdom){
			jdom.printStackTrace();
		}
		return res;
	}

	public static String getParsingTime(String fileName){
		String res ="";
		Element temp = null;
		try{
			temp = (Element)XPath.selectSingleNode(document,"//file[@name='"+fileName+"']/ParsingTime");
			if(temp == null) res = "unknown"; 
			else res = temp.getValue();
		}
		catch(JDOMException jdom){
			jdom.printStackTrace();
		}
		return res;
	}
	public static void removeAllDTDNodes() {
		root.removeChildren("dtditem");
	}

	public static Vector getEmptyErrors(String fileName){
		List listNodes = null;
		Vector res = new Vector();

		try{
			listNodes = XPath.selectNodes(document,"//file[@name='"+fileName+"']/violation[@type='EMPTY']");
			Iterator iter = listNodes.iterator();
			while(iter.hasNext()){
				Element temp = (Element)iter.next();
				System.out.println("elt name: "+temp.getName());
				String value = temp.getAttributeValue("element");
				res.add(value);
			}
		}
		catch(JDOMException jdom){
			jdom.printStackTrace();
		}
		return res;
	}
	
	public static Hashtable getFileInfo(String fileName) {
		Element file = null;
		Hashtable res = new Hashtable();
		try{
			file = (Element)XPath.selectSingleNode(document,"//file[@name='"+fileName+"']");
		}
		catch(JDOMException jdom){
			jdom.printStackTrace();
		}
		res.put("ParsingTime", file.getChildText("ParsingTime"));
		List emptylist = null;
		try{
			emptylist = XPath.selectNodes(file,"//violation[@type='EMPTY']");
			Iterator iter = emptylist.iterator();
			while(iter.hasNext()){
				Element temp = (Element)iter.next();
				System.out.println();
				res.put("EMPTY", temp.getAttributeValue("element"));
			}
		}
		catch(JDOMException jdom){
			jdom.printStackTrace();
		}
		List anylist = null;
		try{
			anylist = XPath.selectNodes(file,"//violation[@type='ANY']");
			Iterator iter = anylist.iterator();
			while(iter.hasNext()){
				Element temp = (Element)iter.next();
				System.out.println();
				res.put("ANY", temp.getAttributeValue("element"));
			}
		}
		catch(JDOMException jdom){
			jdom.printStackTrace();
		}
		return res;
	}

	public static Vector getAnyErrors(String fileName){
		List listNodes = null;
		Vector res = new Vector();
		try{
			listNodes = XPath.selectNodes(document,"//file[@name='"+fileName+"']/violation[@type='ANY']");
			Iterator iter = listNodes.iterator();
			while(iter.hasNext()){
				Element temp = (Element)iter.next();
				String value = temp.getAttributeValue("element");
				res.add(value);
			}
		}
		catch(JDOMException jdom){
			jdom.printStackTrace();
		}
		return res;
	}

	public static Vector getExceptions(String fileName){
		List listNodes = null;
		Vector res = new Vector();
		try{
			listNodes = XPath.selectNodes(document,"//file[@nom='"+fileName+"']/exception");
			Iterator iter = listNodes.iterator();
			while(iter.hasNext()){
				Element temp = (Element)iter.next();
				String value = temp.getValue();
				if(!value.equals("null"))	res.add(value);
			}
		}
		catch(JDOMException jdom){
			jdom.printStackTrace();
		}
		return res;
	}


}
